package com.fishery.refrigeratory.service.Impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fishery.entity.GlobalException;
import com.fishery.entity.StatusCode;
import com.fishery.refrigeratory.entity.Refrigeratory;
import com.fishery.refrigeratory.entity.RefrigeratoryInInfo;
import com.fishery.refrigeratory.mapper.RefrigeratoryInInfoMapper;
import com.fishery.refrigeratory.mapper.RefrigeratoryMapper;
import com.fishery.refrigeratory.mapper.RefrigeratoryOutInfoMapper;
import com.fishery.refrigeratory.service.RefrigeratoryInInfoService;
import com.fishery.refrigeratory.service.RefrigeratoryOutInfoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;

@Service
public class RefrigeratoryInInfoServiceImpl extends ServiceImpl<RefrigeratoryInInfoMapper, RefrigeratoryInInfo> implements RefrigeratoryInInfoService {

    @Autowired
    private RefrigeratoryInInfoMapper refrigeratoryInInfoMapper;

    @Autowired
    private RefrigeratoryMapper refrigeratoryMapper;

    @Autowired
    private RefrigeratoryOutInfoMapper refrigeratoryOutInfoMapper;

    /**
     * 根据冷库id查询冷库的入库信息
     * @return
     */
    @Override
    public List<RefrigeratoryInInfo> selectInfoBytRefrigeratoryId(String refrigeratoryId) {
        QueryWrapper<RefrigeratoryInInfo> wrapper = new QueryWrapper<>();
        wrapper.eq("refrigeratory_id", refrigeratoryId);
        return refrigeratoryInInfoMapper.selectList(wrapper);
    }

    /**
     * 根据冷库id分页查询冷库的入库信息
     * @param refrigeratoryId
     * @return
     */
    @Override
    public Page<RefrigeratoryInInfo> selectPageInfoByRefrigeratoryId(String refrigeratoryId, Integer page, Integer size) {
        QueryWrapper<RefrigeratoryInInfo> wrapper = new QueryWrapper<RefrigeratoryInInfo>();
        Page<RefrigeratoryInInfo> infoPage = new Page<RefrigeratoryInInfo>(page, size);
        wrapper.eq("refrigeratory_id", refrigeratoryId);
        refrigeratoryInInfoMapper.selectPage(infoPage, wrapper);
        return infoPage;
    }

    /**
     * 根据基地id查询冷库的入库信息
     * @param refrigeratoryList
     * @return
     */
    @Override
    public List<RefrigeratoryInInfo> selectInfoByBaseId(List<Refrigeratory> refrigeratoryList) {
        QueryWrapper<RefrigeratoryInInfo> wrapper = new QueryWrapper<>();
        ArrayList<String> resultList = new ArrayList<>();
        refrigeratoryList.forEach(item->{
            resultList.add(item.getId());
        });
        wrapper.in("refrigeratory_id", resultList);
        return refrigeratoryInInfoMapper.selectList(wrapper);
    }

    /**
     * 根据基地id分页查询冷库的入库信息
     * @param refrigeratoryList
     * @param page
     * @param size
     * @return
     */
    @Override
    public Page<RefrigeratoryInInfo> selectPageInfoByBaseId(List<Refrigeratory> refrigeratoryList, Integer page, Integer size) {
        QueryWrapper<RefrigeratoryInInfo> wrapper = new QueryWrapper<>();
        Page<RefrigeratoryInInfo> infopage = new Page<>(page, size);
        ArrayList<String> resultList = new ArrayList<>();
        refrigeratoryList.forEach(item->{
            resultList.add(item.getId());
        });
        wrapper.in("refrigeratory_id", resultList);
        refrigeratoryInInfoMapper.selectPage(infopage, wrapper);
        return infopage;
    }

    /**
     * 查询所有入库信息（不限于基地和冷库）
     * @return
     */
    @Override
    public List<RefrigeratoryInInfo> selectAllInfo() {
        return refrigeratoryInInfoMapper.selectList(null);
    }

    /**
     * 分页查询所有入库信息（不限于基地和冷库）
     * @return
     */
    @Override
    public Page<RefrigeratoryInInfo> selectPageAllInfo(Integer page, Integer size) {
        Page<RefrigeratoryInInfo> infoPage = new Page<>(page, size);
        refrigeratoryInInfoMapper.selectPage(infoPage, null);
        return infoPage;
    }

    /**
     * 新增入库信息
     * @param refrigeratoryInInfo
     * @return
     */
    @Override
    @Transactional
    public int insertInInfo(RefrigeratoryInInfo refrigeratoryInInfo) {
        if (refrigeratoryInInfo == null) {
            return 0;
        }
        //如果库存已满，则直接返回
        //如果冷库不存在则退出
        Refrigeratory refrigeratory = refrigeratoryMapper.selectById(refrigeratoryInInfo.getRefrigeratoryId());
        if (refrigeratory == null) {
            return 0;
        }
        //获得当前冷库总容量
        double refrigeratoryCapacity = refrigeratory.getRefrigeratoryCapacity();
        //获得当前冷库已用容量
        double refrigeratoryUsedCapacity = refrigeratory.getRefrigeratoryUsedCapacity();
        //当前要加入容量
        double refrigeratoryInCapacity = refrigeratoryInInfo.getRefrigeratoryInCapacity();
        //剩余可用容量
        double surplus = refrigeratoryCapacity - refrigeratoryUsedCapacity;
        //如果加入容量超过可用容量，那么直接返回出错
        if (refrigeratoryInCapacity > surplus) {
            throw new GlobalException(StatusCode.ERROR,"新增入库信息失败！！！当前容量不足以存储，只剩余"+ surplus + "kg的容量");
        }
        //如果经过上面测试，则判定成功容量合法
        //相加之后容量
        double add = refrigeratoryUsedCapacity + refrigeratoryInCapacity;
        refrigeratory.setRefrigeratoryUsedCapacity(add);
        refrigeratoryMapper.updateById(refrigeratory);
        return refrigeratoryInInfoMapper.insert(refrigeratoryInInfo);
    }

    /**
     * 删除入库信息
     * @param id
     * @return
     */
    @Override
    @Transactional
    public int deleteInInfo(String id) {
        //得到入库信息
        RefrigeratoryInInfo refrigeratoryInInfo = refrigeratoryInInfoMapper.selectById(id);
        if (refrigeratoryInInfo == null) {
            throw new GlobalException(StatusCode.ERROR, "该冷库入库信息不存在，或已被删除");      //如果是多次删除一个冷库那么第二次获取Info的时候会触发异常。
        }
        //得到入库信息对应的冷库
        Refrigeratory refrigeratory = refrigeratoryMapper.selectById(refrigeratoryInInfo.getRefrigeratoryId());
        if (refrigeratory == null) {
            throw new GlobalException(StatusCode.ERROR, "找不到该入库信息对应的冷库");
        }
        //得到冷库已用容量
        double refrigeratoryUsedCapacity = refrigeratory.getRefrigeratoryUsedCapacity();
        //得到当前入库信息的入库容量
        double refrigeratoryInCapacity = refrigeratoryInInfo.getRefrigeratoryInCapacity();
        //剩余容量
        refrigeratoryUsedCapacity = refrigeratoryUsedCapacity - refrigeratoryInCapacity;
        //更新容量（入库记录消失代表其对应所有出库记录也要消失）
        refrigeratory.setRefrigeratoryUsedCapacity(refrigeratoryUsedCapacity);
        refrigeratoryOutInfoMapper.deleteByRefrigeratoryInId(refrigeratoryInInfo.getId());
        refrigeratoryMapper.updateById(refrigeratory);
        return refrigeratoryInInfoMapper.deleteById(refrigeratoryInInfo.getId());
    }

    /**
     * 更新入库信息
     * @param updateRefrigeratoryInInfo
     * @return
     */
    @Override
    @Transactional
    public int updateInInfo(RefrigeratoryInInfo updateRefrigeratoryInInfo) {
        //得到冷库的已用容量,如果冷库不存在则退出
        Refrigeratory refrigeratory = refrigeratoryMapper.selectById(updateRefrigeratoryInInfo.getRefrigeratoryId());
        if (refrigeratory == null) {
            throw new GlobalException(StatusCode.ERROR, "找不到该入库信息对应的冷库");
        }
        RefrigeratoryInInfo refrigeratoryInInfo = refrigeratoryInInfoMapper.selectById(updateRefrigeratoryInInfo.getId());
        if (refrigeratoryInInfo == null) {
            throw new GlobalException(StatusCode.ERROR, "该入库对象不存在或已被删除");
        }
        //得到之前入库的入库容量,
        double beforeCapacity = refrigeratoryInInfo.getRefrigeratoryInCapacity();
        //得到要修改的容量
        double updateCapacity = updateRefrigeratoryInInfo.getRefrigeratoryInCapacity();
        //如果修改了容量超过我们的最大容量，那么修改失败。
        //如果要修改的容量和之前入库时的代表，那就代表这个修改不是为了修改容量，直接跳过
        if (updateCapacity == beforeCapacity) {
            return refrigeratoryInInfoMapper.updateById(updateRefrigeratoryInInfo);
        } else {
            //查看已经出库容量的总和
            Double count = refrigeratoryInInfo.getRefrigeratoryInUsedCapacity();
            //得到现在已用容量
            double NowCapacity = refrigeratory.getRefrigeratoryUsedCapacity();
            //得到冷库的总容量
            double AllCapacity = refrigeratory.getRefrigeratoryCapacity();
            //相减得到入库之前的已用容量
            double subtract = NowCapacity - beforeCapacity;
            //可以修改容量的最大值
            double max = AllCapacity - subtract;
            //如果已用容量-之前的+现在修改的容量 > 总容量 则修改失败
            double add = subtract + updateCapacity;
            if (add > AllCapacity) {
                throw new GlobalException(StatusCode.ERROR, "修改失败,修改的容量过大，请控制修改后的容量在" + max + "kg之内");
            }
            if (add < count) {
                throw new GlobalException(StatusCode.ERROR, "修改失败,修改的容量小于已经出库的容量！");
            }
            refrigeratory.setRefrigeratoryUsedCapacity(add);
        }
        refrigeratoryMapper.updateById(refrigeratory);
        return refrigeratoryInInfoMapper.updateById(updateRefrigeratoryInInfo);
    }
}
